package moltencore.game;

import moltencore.config.Config;
import org.apache.log4j.Logger;

import java.util.Collection;
import java.util.LinkedList;

public class GameTimeattack extends Game {
	private static Logger logger = Logger.getLogger(GameTimeattack.class);

	private static final float TIME_SECONDS = 20;

	private float secondsLeft = TIME_SECONDS;
	private float lastSecondsLeft = secondsLeft;

	public GameTimeattack(long hostIdentification) {
		super(hostIdentification);
	}

	@Override
	protected void gameStartHook() {
		super.gameStartHook();
		notifyListenersTimeLeft(secondsLeft);
	}

	@Override
	protected void updateHook(float elapsedSeconds) {
		super.updateHook(elapsedSeconds);
		if(secondsLeft > 0) {
			secondsLeft -= elapsedSeconds;
			if(secondsLeft < 0) {
				secondsLeft = 0;
			}
			if(lastSecondsLeft - secondsLeft >= 1) {
				lastSecondsLeft = secondsLeft;
				notifyListenersTimeLeft(secondsLeft);
			}
		}
	}

	@Override
	protected void reflectOnFieldUpdate(Field field) {
		if(field.isBusted()) {
			loserFields.add(field);
		}
	}

	@Override
	protected void handlePossibleGameEnd() {
		// the game has ended if every field but one has lost
		if(loserFields.size() == fields.size() - 1) {
			// find the one winner field
			for(Field field : this.getFields()) {
				if(!loserFields.contains(field)) {
					winnerFields.add(field);
				}
			}
			setState(State.Ended);
		}
		else if(secondsLeft == 0) {
			Field highestScoredField = null;
			for(Field field : this.getFields()) {
				if(highestScoredField == null) {
					highestScoredField = field;
					continue;
				}
				if(field.getScore() < highestScoredField.getScore()) {
					continue;
				}
				// if there is a tie between 2+ players the game moves on until one of them lies ahead
				else if(field.getScore() == highestScoredField.getScore()) {
					highestScoredField = null;
					break;
				}
			}
			if(highestScoredField != null) {
				winnerFields.add(highestScoredField);
				// find all losers
				for(Field field : this.getFields()) {
					if(!loserFields.contains(field) && !winnerFields.contains(field)) {
						loserFields.add(field);
					}
				}
				setState(State.Ended);
			}
		}
		if(getState() == State.Ended) {
			notifyListenersGameEnded(winnerFields, loserFields);
		}
	}

	protected void notifyListenersTimeLeft(float secondsLeft) {
		for(IGameEventListener gameEventListener : getListeners()) {
			gameEventListener.timeLeft(secondsLeft);
		}
	}
}